use std::{fs::File, io::Write};

use askama_axum::IntoResponse;
use axum::{extract::Multipart, Json};
use crate::core::xerror::{GLOBALERROR, XErrors};
use crate::types::backend::upload_type::UploadRow;


pub async fn upload_handler(mut multipart: Multipart) -> impl IntoResponse{
    let error = XErrors::new();
    let upload = multipart.next_field().await;
    let field_opt = match upload {
        Ok(field) => field,
        Err(e) => {
            let db_error = e.to_string();
            return Json(UploadRow {
                code: GLOBALERROR::UPLOADFAILED as i32,
                msg: db_error,
                url: "".to_string()
            });
        }
    };
    let field = match field_opt {
        Some(field) => field,
        None => {
            let err_msg = error.get_error(GLOBALERROR::UPLOADFAILED);
            return Json(UploadRow {
                code: GLOBALERROR::UPLOADFAILED as i32,
                msg: err_msg,
                url: "".to_string()
            });
        }
    };

    let file_name = field.file_name().unwrap_or("");
    if file_name.is_empty() {
        let err_msg = error.get_error(GLOBALERROR::UPLOADFAILED);
        return Json(UploadRow {
            code: GLOBALERROR::UPLOADFAILED as i32,
            msg: err_msg,
            url: "".to_string()
        });
    }
    
    
    let save_path = "./upload/".to_string() + file_name;
    let file = File::create(&save_path);
    let mut save_file = match file {
        Ok(file) => file,
        Err(e) => {
            let db_error = e.to_string();
            return Json(UploadRow {
                code: GLOBALERROR::UPLOADFAILED as i32,
                msg: db_error,
                url: "".to_string()
            });
        }
    };
    let buf = &field.bytes().await;
    match buf {
        Ok(buffer) => {
            let res = save_file.write_all(buffer);
            match res {
                Ok(_) => {
                    // 去掉save_path前面的./
                    let save_path = save_path.trim_start_matches(".");
                    let err_msg = error.get_error(GLOBALERROR::UPLOADSUCCESS);
                    return Json(UploadRow {
                        code: GLOBALERROR::UPLOADSUCCESS as i32,
                        msg: err_msg,
                        url: save_path.to_string()
                    });
                },
                Err(e) => {
                    let db_error = e.to_string();
                    return Json(UploadRow {
                        code: GLOBALERROR::UPLOADFAILED as i32,
                        msg: db_error,
                        url: "".to_string()
                    });
                }
            }
        },
        Err(e) => {
            let db_error = e.to_string();
            return Json(UploadRow {
                code: GLOBALERROR::UPLOADFAILED as i32,
                msg: db_error,
                url: "".to_string()
            });
        }
    }

}